package com.meixiang.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;

import com.meixiang.R;
import com.meixiang.tool.Tool;


public class CircularProgressBar extends View {
	/**
	 * used to save the super state on configuration change
	 */
	private static final String INSTANCE_STATE_SAVEDSTATE = "saved_state";

	/**
	 * used to save the progress on configuration changes
	 */
	private static final String INSTANCE_STATE_PROGRESS = "progress";

	/**
	 * used to save the marker progress on configuration changes
	 */
	private static final String INSTANCE_STATE_MARKER_PROGRESS = "marker_progress";

	/**
	 * used to save the background color of the progress
	 */
	private static final String INSTANCE_STATE_PROGRESS_BACKGROUND_COLOR = "progress_background_color";

	/**
	 * used to save the color of the progress
	 */
	private static final String INSTANCE_STATE_PROGRESS_COLOR = "progress_color";

	/**
	 * used to save and restore the visibility of the thumb in this instance
	 */
	private static final String INSTANCE_STATE_THUMB_VISIBLE = "thumb_visible";

	/**
	 * used to save and restore the visibility of the marker in this instance
	 */
	private static final String INSTANCE_STATE_MARKER_VISIBLE = "marker_visible";

	/**
	 * The rectangle enclosing the circle.矩形封闭循环。
	 */
	private final RectF mCircleBounds = new RectF();

	/**
	 * the paint for the background.油漆的背景。
	 */
	private Paint mBackgroundColorPaint = new Paint();

	/**
	 * The stroke width used to paint the circle.笔划宽度用来画圆。
	 */
	private int mCircleStrokeWidth = 20;

	/**
	 * The gravity of the view. Where should the Circle be drawn within the
	 * given bounds
	 *
	 * {@link #computeInsets(int, int)}
	 */
	private int mGravity = Gravity.CENTER;

	/**
	 * The Horizontal inset calcualted in {@link #computeInsets(int, int)}
	 * depends on {@link #mGravity}.
	 */
	private int mHorizontalInset = 0;

	/**
	 * true if not all properties are set. then the view isn't drawn and there
	 * are no errors in the LayoutEditor
	 */
	private boolean mIsInitializing = true;
	/**
	 * the overdraw is true if the progress is over 1.0.
	 */
	private boolean mOverrdraw = false;

	/**
	 * The current progress.
	 */
	private float mProgress = 0.3f;

	/**
	 * The color of the progress background.
	 */
	private int mProgressBackgroundColor;

	/**
	 * the color of the progress.
	 */
	private int mProgressColor;

	/**
	 * paint for the progress.
	 */
	private Paint mProgressColorPaint;

	/**
	 * Radius of the circle
	 *
	 * <p>
	 * Note: (Re)calculated in {@link #onMeasure(int, int)}.
	 * </p>
	 */
	private float mRadius;



	/**
	 * The Thumb pos x.
	 *
	 * Care. the position is not the position of the rotated thumb. The position
	 * is only calculated in {@link #onMeasure(int, int)}
	 */
	private float mThumbPosX;

	/**
	 * The Thumb pos y.
	 *
	 * Care. the position is not the position of the rotated thumb. The position
	 * is only calculated in {@link #onMeasure(int, int)}
	 */
	private float mThumbPosY;

	/**
	 * The pointer width (in pixels).指针的宽度(以像素为单位)。
	 */
	private int mThumbRadius = 20;

	/**
	 * The Translation offset x which gives us the ability to use our own
	 * coordinates system.
	 */
	private float mTranslationOffsetX;

	/**
	 * The Translation offset y which gives us the ability to use our own
	 * coordinates system.
	 */
	private float mTranslationOffsetY;

	/**
	 * The Vertical inset calcualted in {@link #computeInsets(int, int)} depends
	 * on {@link #mGravity}..
	 */
	private int mVerticalInset = 0;
	private Context context;


	private String centerString;
	private int textSize;
	private int textColor;

	public int getTextColor() {
		return textColor;
	}

	public void setTextColor(int textColor) {
		this.textColor = textColor;
	}

	public int getTextSize() {
		return textSize;
	}

	public void setTextSize(int textSize) {
		this.textSize = textSize;
	}

	public String getCenterString() {
		return centerString;
	}

	public void setCenterString(String centerString) {
		this.centerString = centerString;
	}

	/**
	 * Instantiates a new holo circular progress bar.
	 *
	 * @param context
	 *            the context
	 */
	public CircularProgressBar(final Context context) {
		this(context, null);
		this.context=context;
	}

	/**
	 * Instantiates a new holo circular progress bar.
	 *
	 * @param context
	 *            the context
	 * @param attrs
	 *            the attrs
	 */
	public CircularProgressBar(final Context context,
							   final AttributeSet attrs) {
		this(context, attrs, R.attr.circularProgressBarStyle);
		this.context=context;
	}

	/**
	 * Instantiates a new holo circular progress bar.
	 *
	 * @param context
	 *            the context
	 * @param attrs
	 *            the attrs
	 * @param defStyle
	 *            the def style
	 */
	public CircularProgressBar(final Context context,
							   final AttributeSet attrs, final int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;

		// load the styled attributes and set their properties
		final TypedArray attributes = context.obtainStyledAttributes(attrs,
				R.styleable.HoloCircularProgressBar, defStyle, 0);
		if (attributes != null) {
			try {
				setProgressColor(attributes.getColor(
						R.styleable.HoloCircularProgressBar_progress_color,0xfff78182));//设置已完成颜色
				setProgressBackgroundColor(attributes
						.getColor(
								R.styleable.HoloCircularProgressBar_progress_background_color,0xffFEF0F0));//设置未完成颜色
				setProgress(attributes.getFloat(
						R.styleable.HoloCircularProgressBar_progress, 0.0f));
				setWheelSize((int) attributes.getDimension(
						R.styleable.HoloCircularProgressBar_stroke_width, 20));

				mGravity = attributes.getInt(
						R.styleable.HoloCircularProgressBar_android_gravity,
						Gravity.CENTER);
			} finally {
				// make sure recycle is always called.
				attributes.recycle();
			}
		}

		mThumbRadius = mCircleStrokeWidth * 2;

		updateBackgroundColor();


		updateProgressColor();

		// the view has now all properties and can be drawn
		mIsInitializing = false;

	}

	/**
	 * Compute insets.
	 * 
	 * <pre>
	 *  ______________________
	 * |_________dx/2_________|
	 * |......| /'''''\|......|
	 * |-dx/2-|| View ||-dx/2-|
	 * |______| \_____/|______|
	 * |________ dx/2_________|
	 * </pre>
	 * 
	 * @param dx
	 *            the dx the horizontal unfilled space
	 * @param dy
	 *            the dy the horizontal unfilled space
	 */
	@SuppressLint("NewApi")
	private void computeInsets(final int dx, final int dy) {
		int absoluteGravity = mGravity;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
			absoluteGravity = Gravity.getAbsoluteGravity(mGravity,
					getLayoutDirection());
		}

		switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
		case Gravity.LEFT:
			mHorizontalInset = 0;
			break;
		case Gravity.RIGHT:
			mHorizontalInset = dx;
			break;
		case Gravity.CENTER_HORIZONTAL:
		default:
			mHorizontalInset = dx / 2;
			break;
		}
		switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) {
		case Gravity.TOP:
			mVerticalInset = 0;
			break;
		case Gravity.BOTTOM:
			mVerticalInset = dy;
			break;
		case Gravity.CENTER_VERTICAL:
		default:
			mVerticalInset = dy / 2;
			break;
		}
	}

	public int getCircleStrokeWidth() {
		return mCircleStrokeWidth;
	}

	/**
	 * Gets the current rotation.
	 * 
	 * @return the current rotation
	 */
	private float getCurrentRotation() {
		return 360 * mProgress;
	}



	/**
	 * gives the current progress of the ProgressBar. Value between 0..1 if you
	 * set the progress to >1 you'll get progress % 1 as return value
	 * 
	 * @return the progress
	 */
	public float getProgress() {
		return mProgress;
	}

	/**
	 * Gets the progress color.
	 * 
	 * @return the progress color
	 */
	public int getProgressColor() {
		return mProgressColor;
	}



	@Override
	protected void onDraw(final Canvas canvas) {

		// All of our positions are using our internal coordinate system.
		// Instead of translating
		// them we let Canvas do the work for us.
		canvas.translate(mTranslationOffsetX, mTranslationOffsetY);


		Paint paintCircle=new Paint();
		paintCircle.setStyle(Paint.Style.FILL);
		paintCircle.setAntiAlias(true);
		paintCircle.setColor(mProgressColor);
//		paintCircle.setColor(ContextCompat.getColor(context,R.color.white));
		//mCircleStrokeWidth
		canvas.drawCircle(mCircleBounds.centerX(), mCircleBounds.centerY(), getWidth() / 2 - mProgressColorPaint.getStrokeWidth(), paintCircle);
		final float progressRotation = getCurrentRotation();
		// draw the background

		if (!mOverrdraw) {
			canvas.drawArc(mCircleBounds, 270, -(360 - progressRotation),
					false, mBackgroundColorPaint);
		}
		// draw the progress or a full circle if overdraw is true
		canvas.drawArc(mCircleBounds, 270, mOverrdraw ? 360 : progressRotation,
				false, mProgressColorPaint);

//		Paint paint=new Paint();
//		//更具手机屏幕分辨率来
//		paint.setTextSize(Tool.dip2px(context,(float)20));
//		int percent = 100; // 中间的进度百分比，先转换成float在进行除法运算，不然都为0
//		paint.setTextAlign(Paint.Align.CENTER);
//		canvas.drawText(percent+"%", centerX, centerY - 2 * 20 / 3+mBackgroundColorPaint.getStrokeWidth(), paint); // 画出进度百分比

	}
	private float centerX;  //圆心X坐标
	private float centerY;  //圆心Y坐标
	@Override
	protected void onMeasure(final int widthMeasureSpec,
			final int heightMeasureSpec) {
		final int height = getDefaultSize(getSuggestedMinimumHeight()
				+ getPaddingTop() + getPaddingBottom(), heightMeasureSpec);
		final int width = getDefaultSize(getSuggestedMinimumWidth()
				+ getPaddingLeft() + getPaddingRight(), widthMeasureSpec);

		final int diameter;
		if (heightMeasureSpec == MeasureSpec.UNSPECIFIED) {
			// ScrollView
			diameter = width;
			computeInsets(0, 0);
		} else if (widthMeasureSpec == MeasureSpec.UNSPECIFIED) {
			// HorizontalScrollView
			diameter = height;
			computeInsets(0, 0);
		} else {
			// Default
			diameter = Math.min(width, height);
			computeInsets(width - diameter, height - diameter);
		}

		setMeasuredDimension(diameter, diameter);

		final float halfWidth = diameter * 0.5f;

		// width of the drawed circle (+ the drawedThumb)
		final float drawedWith;
		drawedWith = mCircleStrokeWidth / 2f;
		// -0.5f for pixel perfect fit inside the viewbounds
		mRadius = halfWidth - drawedWith - 0.5f;
		mCircleBounds.set(-mRadius, -mRadius, mRadius, mRadius);
		// mCircleBounds.set(150, 20, 180, 40);
		mThumbPosX = (float) (mRadius * Math.cos(0));
		mThumbPosY = (float) (mRadius * Math.sin(0));

		mTranslationOffsetX = halfWidth + mHorizontalInset;
		mTranslationOffsetY = halfWidth + mVerticalInset;

	}

	@Override
	protected void onRestoreInstanceState(final Parcelable state) {
		if (state instanceof Bundle) {
			final Bundle bundle = (Bundle) state;
			setProgress(bundle.getFloat(INSTANCE_STATE_PROGRESS));

			final int progressColor = bundle
					.getInt(INSTANCE_STATE_PROGRESS_COLOR);
			if (progressColor != mProgressColor) {
				mProgressColor = progressColor;
				updateProgressColor();
			}

			final int progressBackgroundColor = bundle
					.getInt(INSTANCE_STATE_PROGRESS_BACKGROUND_COLOR);
			if (progressBackgroundColor != mProgressBackgroundColor) {
				mProgressBackgroundColor = progressBackgroundColor;
				updateBackgroundColor();
			}


			super.onRestoreInstanceState(bundle
					.getParcelable(INSTANCE_STATE_SAVEDSTATE));
			return;
		}

		super.onRestoreInstanceState(state);
	}

	@Override
	protected Parcelable onSaveInstanceState() {
		final Bundle bundle = new Bundle();
		bundle.putParcelable(INSTANCE_STATE_SAVEDSTATE,
				super.onSaveInstanceState());
		bundle.putFloat(INSTANCE_STATE_PROGRESS, mProgress);
		bundle.putInt(INSTANCE_STATE_PROGRESS_COLOR, mProgressColor);
		bundle.putInt(INSTANCE_STATE_PROGRESS_BACKGROUND_COLOR,
				mProgressBackgroundColor);

		return bundle;
	}



	/**
	 * Sets the progress.
	 * 
	 * @param progress
	 *            the new progress
	 */
	public void setProgress(final float progress) {
		if (progress == mProgress) {
			return;
		}

		if (progress == 1) {
			mOverrdraw = false;
			mProgress = 1;
		} else {
			if (progress >= 1) {
				mOverrdraw = true;
			} else {
				mOverrdraw = false;
			}
			mProgress = progress % 1.0f;
		}

		if (!mIsInitializing) {
			invalidate();
		}
	}

	/**
	 * Sets the progress background color.
	 * 
	 * @param color
	 *            the new progress background color
	 */
	public void setProgressBackgroundColor(final int color) {
		mProgressBackgroundColor = color;
		updateBackgroundColor();
	}

	/**
	 * Sets the progress color.
	 * 
	 * @param color
	 *            the new progress color
	 */
	public void setProgressColor(final int color) {
		mProgressColor = color;

		updateProgressColor();
	}



	/**
	 * Sets the wheel size.
	 * 
	 * @param dimension
	 *            the new wheel size
	 */
	public void setWheelSize(final int dimension) {
		mCircleStrokeWidth = dimension;

		// update the paints
		updateBackgroundColor();
		updateProgressColor();
	}

	/**
	 * updates the paint of the background
	 */
	private void updateBackgroundColor() {
		// 其余未完成进度颜色
		mBackgroundColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mBackgroundColorPaint.setColor(mProgressBackgroundColor);
		mBackgroundColorPaint.setStyle(Paint.Style.STROKE);
		mBackgroundColorPaint.setStrokeWidth(mCircleStrokeWidth);

		invalidate();
	}



	/**
	 * updates the paint of the progress and the thumb to give them a new visual
	 * style
	 */
	private void updateProgressColor() {
		// 外圈，已完成进度颜色
		mProgressColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mProgressColorPaint.setColor(mProgressColor);
		mProgressColorPaint.setStyle(Paint.Style.STROKE);// 设置空心
		mProgressColorPaint.setStrokeWidth(mCircleStrokeWidth);

		invalidate();
	}

	private static final int START = 1;
	private static final int MAX=100;
	private float maxProgress=0,curProgress=0;
	public synchronized void setAnimProgress(float progress) {
		maxProgress = progress;
		curProgress = 0;
		mHandler.sendEmptyMessageDelayed(START, 200);
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
				case START:
					if (curProgress < maxProgress) {
						setProgress(curProgress);
						curProgress += 0.03;
						mHandler.sendEmptyMessageDelayed(START, 50);
					} else {
						setProgress(curProgress);
					}
					break;
				case MAX:
					if (curProgress < maxProgress) {
						setProgress(curProgress);
						curProgress += 1;
						mHandler.sendEmptyMessageDelayed(MAX, 50);
					} else {
						setProgress(curProgress);
					}
					if(curProgress==100){
						Animation animationUP = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
								Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,-1.0f);
						animationUP.setDuration(600);
						animationUP.setFillAfter(true);
						CircularProgressBar.this.setProgress(0);
						CircularProgressBar.this.setVisibility(View.GONE);
					}
					break;
				default:
					setProgress(curProgress);
					break;
			}
		};
	};
}
